package tester;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

/**
 * Provides an interface to retrieve n-gram probabilities
 * 
 * @author J. Su
 * @author C. Liang
 */
public class Model {
    HashMap<String,Double> static_unigram = new HashMap<String,Double>();
    HashMap<String,Double> static_bigram = new HashMap<String,Double>();
    HashMap<String,Double> static_trigram = new HashMap<String,Double>();

    /**
     * Parses a file and builds a model
     * 
     * The file may contain multiple n-gram models
     * Only unigrams to trigrams are supported
     * Format of the file should be:
     * tag1 tag2 tag3   prob
     * Note that tag3 and prob are separated by a tab
     * This means: P(tag3|tag1 tag2) = prob
     * 
     * @param filename
     */
    public Model(String filename){        
        
        try{
            BufferedReader in = new BufferedReader(new FileReader(filename));
            String line="";
            String current_model = "";
            while((line=in.readLine())!=null){
                if(line.indexOf("Unigram")>=0){
                    current_model = "unigram";
                    continue;
                }else if(line.indexOf("Bigram")>=0){
                    current_model = "bigram";
                    continue;
                }else if(line.indexOf("Trigram")>=0){
                    current_model = "trigram";
                    continue;
                }
                String[] model = line.split("\t");
                if(current_model.equals("unigram")){                    
                    static_unigram.put(model[0], Double.valueOf(model[1]));
                }else if(current_model.equals("bigram")){                   
                    static_bigram.put(model[0], Double.valueOf(model[1]));
                }else{
                    try {
                        static_trigram.put(model[0], Double.valueOf(model[1]));
                    }
                    catch (ArrayIndexOutOfBoundsException e) {
                        System.err.println("Error: the model file is not in the right format.");
                        System.err.println("The tags and probability should be separated by a tab.");
                        System.err.println("Problematic line: " + line);
                        
                        throw e;
                    }
                }
            }
            in.close();
        }catch(IOException e){}
    }
    
    /**
     * Returns the probability of the sequence
     * 
     * terms should be of the form:
     * tag1 [tag2 [tag3]]
     * 
     * @param terms
     * @param nGram - 1 for unigram, 2 for bigram, 3 for trigram
     * @return
     */
    public double getStaticModel(String terms,int nGram){
        double dResult = 0.0;
        
        switch(nGram){
        case 1:
            dResult = static_unigram.get(terms);
            break;
        case 2:
            dResult = static_bigram.get(terms);
            break;
        case 3:
            dResult = static_trigram.get(terms);
            break;          
        }
        
        return dResult;
    }

    
    /**
     * Finds the highest order model available
     * 
     * @return 1 for unigram, 2 for bigram, 3 for trigram, -1 for error
     */
    public int getN() {
        if (!static_trigram.isEmpty()) {
            return 3;
        }
        if (!static_bigram.isEmpty()) {
            return 2;
        }
        if (!static_unigram.isEmpty()) {
            return 1;
        }
        else {
            return -1;
        }
    }
}
